/**
 * 生成一个随机颜色字符串
 * @param {BOOLEAN} type 是否十六进制返回
 * @return {STRING} 随机颜色的字符串
 */
function randomColor(type) {
  if (!type) {
    var res =
      "rgb(" +
      rangeRandom(0, 255) +
      "," +
      rangeRandom(0, 255) +
      "," +
      rangeRandom(0, 255) +
      ")";
    return res;
  }

  var str = "#";
  for (var i = 0; i < 3; i++) {
    var n = rangeRandom(0, 255).toString(16);
    if (n.length === 1) n = "0" + n;
    str += n;
  }
  return str;
}

/**
 * 范围内的随机整数
 * @param {NUMBER} a 数字1
 * @param {NUMBER} b
 * @return {NUMBER} 随机数字
 */
function rangeRandom(a, b) {
  var max = Math.max(a, b);
  var min = Math.min(a, b);
  var res = Math.floor(Math.random() * (max - min + 1) + min);
  return res;
}

/**
 * setCookie 设置 cookie 的方法
 * @param {STRING} key cookie 的 key
 * @param {STRING} value cookie 的 value
 * @param {NUMBER} expires 多少秒以后过期
 * @param {STRING} path cookie 存储路径
 */
function setCookie(key, value, expires, path) {
  //准备一个标准cookie内容
  var str = key + "=" + value;
  if (expires) {
    //处理时间
    var time = new Date();
    time.setTime(time.getTime() - 1000 * 60 * 60 * 8 + expires * 1000);
    str += ";expires =" + time;
  }

  if (path) {
    //处理路径
    str += ";path= " + path;
  }
  //设置
  document.cookie = str;
}

/**
 * getCookie 获取 cookie 的方法
 * @param {STRING} key 选填：你要获取的某一个cookie的key
 * @returns {STRING | OBJECT} 填写参数是指定 key 的值，不填写参数是对象
 */
function getCookie(key) {
  //先把cookie拿过来
  var tmp = document.cookie.split("; ");
  //没传递key，准备一个空对象
  var o = key ? "" : {};
  //遍历tmp
  tmp.forEach(function (item) {
    var t = item.split("=");
    if (key) {
      if (t[0] === key) {
        o = t[1];
      }
    } else {
      //随着循环
      // i === 0 ， t = ['a','100'], t[0] === 'a', t[1] === 100
      o[t[0]] = t[1];
    }
  });
  return o;
}

/**
 * creXhr 创建 ajax 对象
 * @returns {OBJECT} 当前浏览器使用的 ajax 对象
 */
function creXhr() {
  var xhr = null;
  //准备一个变量
  var flag = false;
  //根据各种判断，来给xhr赋值
  var arr = [
    function () {
      return new XMLHttpRequest();
    },
    function () {
      return new ActiveXObject("Microsoft.XMLHTTP");
    },
    function () {
      return new ActiveXObject("Msxml.XMLHTTP");
    },
    function () {
      return new ActiveXObject("Msxml2.XMLHTTP");
    },
  ];

  for (let i = 0; i < arr.length; i++) {
    try {
      xhr = arr[i]();
      //这里的代码可以执行，表示arr[i]函数里面的代码在当前浏览器用的
      creXhr = arr[i];
      flag = true;
      break;
    } catch (e) {}
  }

  //判断flag
  if (!flag) {
    xhr = "您的浏览器不支持ajax，请更换浏览器重试";
    throw new Error(xhr);
  }

  //返回xhr
  return xhr;
}

/**
 * ajax 发送 ajax 请求的方法
 * @param {OBJECT} options 请求的所有配置项
 */
function ajax(options = {}) {
  // options = { } 目的：为了保证你的options 是一个对象
  // 我执行options.xxx 的时候不会报错
  //options.success 和 error 是两个函数类型或者没传进

  //1.参数验证
  //1-1.验证url
  if (!options.url) {
    throw new Error("url 为必填选项");
  }
  //1-2.验证type
  if (
    !(
      options.type == undefined ||
      options.type.toUpperCase() === "GET" ||
      options.type.toUpperCase() === "POST"
    )
  ) {
    throw new Error("目前只接受GET或者POST请求方式");
  }
  //1-3.验证async
  if (!(options.async == undefined || typeof options.async === "boolean")) {
    throw new Error("async需要一个Boolean数据类型");
  }
  //1-4.验证dataType
  if (
    !(
      options.dataType == undefined ||
      options.dataType === "string" ||
      options.dataType === "json"
    )
  ) {
    throw new Error("目前只接受string和json格式解析");
  }
  //1-5.验证data
  if (
    !(
      options.data == undefined ||
      typeof options.data === "string" ||
      Object.prototype.toString.call(options.data) === "[object Object]"
    )
  ) {
    throw new Error("data参数只支持string和object数据类型");
  }
  //1-6.验证success和error
  if (
    !(options.success === undefined || typeof options.success === "function")
  ) {
    throw new Error("success传递一个函数类型");
  }
  if (!(options.error === undefined || typeof options.error === "function")) {
    throw new Error("error传递一个函数类型");
  }
  //代码来到这里，说明options.success 和 error 肯定是一个 undefined 或者 function

  //2.设置一套默认值
  var _default = {
    url: options.url,
    //代码能来到这里，说明undefined get post
    type: options.type || "GET",
    //代码能来到这里，说明undefined true false
    //三元表达式
    async: typeof options.async === "boolean" ? options.async : true,
    //代码能来到这里，说明undefined 'string' 'json'
    dataType: options.dataType || "string",
    //代码能来到这里，说明undefined ' ' { }
    data: options.data || "",
    //如果传递是要给function，就用传递的，否则给一个默认函数
    success: options.success || function () {},
    error: options.error || function () {},
  };
  //到这里，_default.success 和 error肯定是个函数

  //2-2.单独调整一下data
  //代码能来到这里，说明'' {}
  if (typeof _default.data === "object") {
    //准备一个空字符串
    var str = "";
    for (var key in _default.data) {
      str += key + "=" + _default.data[key] + "&";
    }
    //拼接完毕以后，把最后一个为去掉
    _default.data = str.slice(0, -1);
  }
  //3.发送请求
  var xhr = creXhr();

  //3-1.请求地址，如果是GET请求url + '?' + data
  //             如果是POST请求url
  //判断，如果是GET请求，那么我把_default.url 修改一下
  if (_default.type.toUpperCase() === "GET" && _default.data) {
    _default.url += "?" + _default.data;
  }
  xhr.open(_default.type, _default.url, _default.async);
  xhr.onreadystatechange = function () {
    if (xhr.status >= 200 && xhr.status < 300 && xhr.readyState === 4) {
      //3-3.判断dataType 如果是json要解析
      if (_default.dataType === "json") {
        //成功，不需要打印
        //调用_default.success()
        _default.success(JSON.parse(xhr.responseText));
      } else if (_default.dataType === "string") {
        _default.success(xhr.responseText);
      }
    }
    if (xhr.readyState === 4 && xhr.status >= 400) {
      _default.error(xhr.status);
    }
  };

  //3-2.判断是不是post请求
  if (_default.type.toUpperCase() === "POST") {
    xhr.setRequestHeader("content-type", "application/x-www-form-urlencoded");
  }
  xhr.send(_default.data);
}

/**
 * ajax 发送 ajax 请求的方法
 * @param {OBJECT} options 请求的所有配置项
 * @returns {PROMISE} promise 对象
 */
function pAjax(options = {}){
  return new Promise(function(resolve, reject){
    ajax({
      url:options.url,
      data:options.data,
      async:options.async,
      dataType:options.dataType,
      type:options.type,
      success(res){
        resolve(res)
      },
      error(err){
        reject(err)
      }
    })
  })
}

/**
 * 解析查询字符串
 * @param {STRING} str 要解析的查询字符串 
 * @returns {OBJECT} 解析后的结果
 */

function parseQueryString(str) {
  var obj = {}
  if (str) {
    var tmp = str.slice(1).split('&')
    tmp.forEach(function (item) {
      var t = item.split('=')
      obj[t[0]] = t[1]
    })
  }
  return obj
}